/*
 *    Copyright 2011-2012 The Hook Team
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.hook.core.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringEscapeUtils;

/**
 * @author suwuqiang 2011-8-19
 */
public abstract class EnCodeUtil {
	private static final String DEFAULT_URL_ENCODING = "UTF-8";

	/**
	 * 格式化为MD5的字符串
	 * 
	 * @param str
	 * @return String
	 * @throws Exception
	 */
	public static String md5(String str) throws Exception {
		String md5Str = "";
		try {
			MessageDigest messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
			for (byte theByte : messageDigest.digest()) {
				if (Integer.toHexString(0xFF & theByte).length() == 1) {
					md5Str += "0";
					md5Str += Integer.toHexString(0xFF & theByte);
				} else {
					md5Str += Integer.toHexString(0xFF & theByte);
				}
			}
		} catch (Exception e) {
			throw new Exception("MD5 加密出现异常!");
		}
		return md5Str;
	}

	/**
	 * HEX加密
	 * 
	 * @param str
	 * @return String
	 */
	public static String encodeHex(String str) {
		byte[] input = str.getBytes();
		return Hex.encodeHexString(input);
	}

	/**
	 * HEX解密
	 * 
	 * @param input
	 * @return String
	 */
	public static String decodeHex(String input) {
		try {
			return Hex.decodeHex(input.toCharArray()).toString();
		} catch (DecoderException e) {
			throw new IllegalStateException("Hex Decoder exception", e);
		}
	}

	/**
	 * Base64加密, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548)
	 * 
	 * @param str
	 * @return String
	 */
	public static String encodeBase64(String str) {
		byte[] input = str.getBytes();
		return Base64.encodeBase64String(input);
	}

	/**
	 * Base64解密
	 * 
	 * @param str
	 * @return String
	 */
	public static String encodeUrlSafeBase64(String str) {
		byte[] input = str.getBytes();
		return Base64.encodeBase64URLSafeString(input);
	}

	/**
	 * URL 编码, Encode默认为UTF-8
	 * 
	 * @param url
	 * @return String
	 */
	public static String urlEncode(String url) {
		try {
			return URLEncoder.encode(url, DEFAULT_URL_ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw ExceptionUtil.unchecked(e);
		}
	}

	/**
	 * URL 解码
	 * 
	 * @param url
	 * @return String
	 */
	public static String urlDecode(String url) {
		try {
			return URLDecoder.decode(url, DEFAULT_URL_ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw ExceptionUtil.unchecked(e);
		}
	}

	public static String htmlEscape(String html) {
		return StringEscapeUtils.escapeHtml(html);
	}

	public static String htmlUnescape(String htmlEscaped) {
		return StringEscapeUtils.unescapeHtml(htmlEscaped);
	}

	public static String xmlEscape(String xml) {
		return StringEscapeUtils.escapeXml(xml);
	}

	public static String xmlUnescape(String xmlEscaped) {
		return StringEscapeUtils.unescapeXml(xmlEscaped);
	}
}
